package org.xshop.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.transaction.annotation.Transactional;
import org.xshop.bean.Cart;
import org.xshop.bean.ShoppingCart;
import org.xshop.mapper.TShoppingCartMapper;
import org.xshop.model.TGoods;
import org.xshop.model.TGoodsAttribute;
import org.xshop.model.TGoodsPromotion;
import org.xshop.model.TShoppingCart;
import org.xshop.service.ITShoppingCartService;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.weibo.api.motan.config.springsupport.annotation.MotanService;

import top.ibase4j.core.Constants;
import top.ibase4j.core.base.BaseServiceImpl;
import top.ibase4j.core.exception.BusinessException;
import top.ibase4j.core.support.generator.Sequence;
import top.ibase4j.core.util.CacheUtil;
import top.ibase4j.core.util.DataUtil;
import top.ibase4j.core.util.DateUtil;
import top.ibase4j.core.util.InstanceUtil;

/**
 * <p>
 * 购物车 服务实现类
 * </p>
 *
 * @author ShenHuaJie
 * @since 2017-04-23
 */
@MotanService(interfaceClass = ITShoppingCartService.class)
@CacheConfig(cacheNames = "shoppingCart")
public class ShoppingCartService extends BaseServiceImpl<TShoppingCart, TShoppingCartMapper>
implements ITShoppingCartService {
    @Autowired
    private GoodsService goodsService;

    @Override
    public Object queryAll(Map<String, Object> params) {
        ShoppingCart shoppingCart = new ShoppingCart();
        List<TShoppingCart> list = super.queryList(params);
        // 总市场价
        BigDecimal totalAmount = new BigDecimal("0");
        // 总售卖加
        BigDecimal totalAmountShow = new BigDecimal("0");
        BigDecimal skuTotalNum = new BigDecimal("0");

        List<Object> groupCarts = InstanceUtil.newArrayList();
        if (!list.isEmpty()) {
            Object storeId = params.getOrDefault("storeId", null);
            List<Map<String, Object>> skuList = InstanceUtil.newArrayList();
            for (TShoppingCart cart : list) {
                TGoods goods = goodsService.queryById(cart.getSkuId());
                if (goods != null) {
                    if (storeId != null && !storeId.toString().equals(goods.getStoreId().toString())) {
                        continue;
                    }
                    skuTotalNum = skuTotalNum.add(cart.getQuantity());
                    if (goods.getIsPromotion() != null && goods.getIsPromotion() == 1) {
                        TGoodsPromotion promotion = goods.getPromotion();
                        Date now = DateUtil.stringToDate(DateUtil.getDate());
                        if (!promotion.getStartTime().after(now) && !promotion.getEndTime().before(now)) {
                            goods.setSalePrice(promotion.getPrice());
                        }
                    }
                    if (cart.getSkuAttribute() != null && DataUtil.isNotEmpty(goods.getAttributes())) {
                        String[] attrs = cart.getSkuAttribute().toString().split("\\-");
                        for (String attr : attrs) {
                            for (TGoodsAttribute attribute : goods.getAttributes()) {
                                if (attr.equals(attribute.getAttributeValue())) {
                                    goods.setSalePrice(goods.getSalePrice().subtract(attribute.getEffectPrice()));
                                }
                            }
                        }
                    }
                    totalAmount = totalAmount.add(goods.getGoodsPrice());
                    totalAmountShow = totalAmountShow.add(goods.getSalePrice());
                    Map<String, Object> map = InstanceUtil.transBean2Map(goods);
                    map.put("quantity", cart.getQuantity());
                    skuList.add(map);
                } else {
                    super.deleteByEntity(cart);
                }
            }

            // 商店归属
            Map<Long, List<Map<String, Object>>> map = InstanceUtil.newLinkedHashMap();
            for (int i = 0; i < skuList.size(); i++) {
                Map<String, Object> shopping = skuList.get(i);
                Long id = Long.parseLong(shopping.get("storeId").toString());
                if (map.containsKey(id)) {
                    map.get(id).add(shopping);
                } else {
                    List<Map<String, Object>> shoppingCarts = InstanceUtil.newArrayList();
                    shoppingCarts.add(shopping);
                    map.put(id, shoppingCarts);
                }
            }
            JSONArray shopArr = new JSONArray();
            Set<Long> set = map.keySet();
            Iterator<Long> iterator = set.iterator();
            while (iterator.hasNext()) {
                Long id = iterator.next();
                List<Map<String, Object>> shoppingCarts = map.get(id);
                JSONObject storeObj = (JSONObject) JSON.toJSON(shoppingCarts.get(0).get("store"));

                BigDecimal quantitySum = new BigDecimal(0);

                // 商品总费用
                BigDecimal totalAmountFee = new BigDecimal(0);
                for (Map<String, Object> cart : shoppingCarts) {
                    cart.remove("store");
                    quantitySum = quantitySum.add(new BigDecimal(cart.get("quantity").toString()));
                    totalAmountFee = totalAmountFee.add(new BigDecimal(cart.get("salePrice").toString()));
                }
                storeObj.put("shoppingCarts", shoppingCarts);
                storeObj.put("totalAmountFee", 0);
                storeObj.put("totalAmountShow", 0);
                shopArr.add(storeObj);
            }

            Map<String, Object> groupMap = InstanceUtil.newHashMap();
            groupMap.put("groupId", 1);
            groupMap.put("skuList", shopArr);
            groupCarts.add(groupMap);
        }

        shoppingCart.setCartCount(list.size());
        shoppingCart.setGroupCarts(groupCarts);
        shoppingCart.setSkuTotalNum(skuTotalNum);
        shoppingCart.setTotalAmount(totalAmountShow);
        shoppingCart.setTotalAmountShow(totalAmountShow);
        return shoppingCart;
    }

    @Override
    @Transactional
    public Long addCard(Cart cart) {
        String[] skus = cart.getSkuList().split(",");
        String requestId = Sequence.next().toString();
        for (String sku : skus) {
            String[] info = sku.split("\\|");
            String cacheKey = Constants.CACHE_NAMESPACE + "CART-" + info[0];
            if (CacheUtil.getLock(cacheKey, requestId)) {
                try {
                    TGoods goods = goodsService.queryById(Long.valueOf(info[0]));
                    if (goods == null) {
                        throw new BusinessException("商品不存在");
                    }

                    if (goods.getIsSale() != 1) {
                        throw new RuntimeException("商品【" + goods.getGoodsName() + "】未上架.");
                    }

                    // 查询购物车是否存在相同商品，相同则合并，不同则新增
                    @SuppressWarnings("serial")
                    TShoppingCart existingShoppingCart = this.selectOne(new TShoppingCart() {
                        {
                            setMemberId(cart.getMemberId());
                            setSkuId(Long.parseLong(info[0]));
                            setSkuAttribute(info[2]);
                        }
                    });
                    BigDecimal quantity = new BigDecimal(info[1]);
                    if (existingShoppingCart != null) {
                        // 合并购物车(添加商品数量)
                        existingShoppingCart
                        .setQuantity(existingShoppingCart.getQuantity().add(new BigDecimal(info[1])));
                        if (goods.getStock().compareTo(existingShoppingCart.getQuantity()) == -1) {
                            throw new RuntimeException("商品【" + goods.getGoodsName() + "】库存不足.");
                        }
                        this.update(existingShoppingCart);
                    } else {
                        if (goods.getStock().compareTo(quantity) == -1) {
                            throw new RuntimeException("商品【" + goods.getGoodsName() + "】库存不足.");
                        }
                        // 添加购物车
                        // goods.setStock(goods.getStock().subtract(quantity));
                        // goodsService.update(goods);
                        TShoppingCart record = new TShoppingCart();
                        record.setSkuAttribute(info[2]);
                        record.setMemberId(cart.getMemberId());
                        record.setSkuId(Long.valueOf(info[0]));
                        record.setQuantity(quantity);
                        record.setCreateBy(cart.getMemberId());
                        record.setCreateTime(new Date());
                        record.setEnable(1);
                        record.setUpdateBy(cart.getMemberId());
                        record.setUpdateTime(new Date());
                        super.update(record);
                    }

                } finally {
                    CacheUtil.unLock(cacheKey, requestId);
                }
            } else {
                throw new BusinessException("系统繁忙,请稍候再试");
            }
        }
        return (long) skus.length;
    }

    @Override
    @Transactional
    public Object deleteCard(Cart cart) {
        String[] skus = cart.getSkuList().split(",");
        String requestId = Sequence.next().toString();
        for (String sku : skus) {
            String cacheKey = Constants.CACHE_NAMESPACE + "CART-" + sku;
            if (CacheUtil.getLock(cacheKey, requestId)) {
                try {
                    String[] parts = sku.split("\\|");
                    TShoppingCart record = new TShoppingCart();
                    record.setMemberId(cart.getMemberId());
                    record.setSkuAttribute(parts[2]);
                    record.setSkuId(Long.parseLong(parts[0]));
                    record = super.selectOne(record);
                    super.delete(record.getId());
                    /*
                     * TGoods goods =
                     * goodsService.queryById(record.getProductId());
                     * goods.setStock(goods.getStock().add(record.getQuantity())
                     * ); goodsService.update(goods);
                     */
                } finally {
                    CacheUtil.unLock(cacheKey, requestId);
                }
            }
        }
        return skus.length;
    }

    @Override
    public Object updateCard(Cart cart) {
        String[] skus = cart.getSkuList().split(",");
        String requestId = Sequence.next().toString();
        for (String sku : skus) {
            String[] info = sku.split("\\|");
            String cacheKey = Constants.CACHE_NAMESPACE + "CART-" + info[0];
            if (CacheUtil.getLock(cacheKey, requestId)) {
                try {
                    TShoppingCart record = new TShoppingCart();
                    record.setMemberId(cart.getMemberId());
                    record.setSkuAttribute(info[2]);
                    record.setSkuId(Long.parseLong(info[0]));
                    record = super.selectOne(record);
                    BigDecimal quantity = new BigDecimal(info[1]);
                    BigDecimal change = quantity.subtract(record.getQuantity());
                    TGoods goods = goodsService.queryById(Long.valueOf(info[0]));
                    if (goods.getStock().compareTo(change) == -1) {
                        throw new RuntimeException("商品【" + goods.getGoodsName() + "】库存不足.");
                    }
                    // goods.setStock(goods.getStock().subtract(change));
                    // goodsService.update(goods);
                    record.setQuantity(new BigDecimal(info[1]));
                    super.update(record);
                } finally {
                    CacheUtil.unLock(cacheKey, requestId);
                }
            }
        }
        return skus.length;
    }

    @Override
    @Transactional
    public Object updateShoppingCart(Cart cart) {
        Map<String, Object> columnMap = InstanceUtil.newHashMap("member_id", cart.getMemberId());
        deleteByMap(columnMap);
        if (DataUtil.isEmpty(cart.getSkuList())) {
            return null;
        }
        return addCard(cart);
    }
}
